package com.net.xpay.common.service.impl;

import com.net.xpay.common.domain.CheckCode;
import com.net.xpay.common.domain.CheckCodeLog;
import com.net.xpay.common.enums.user.CheckCodeType;
import com.net.xpay.common.manager.CheckCodeLogManager;
import com.net.xpay.common.manager.CheckCodeManager;
import com.net.xpay.core.CoreProperties;
import com.net.xpay.core.constant.CoreConstant;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.helper.EnvironmentHelper;
import com.net.xpay.core.helper.SmsHelper;
import com.net.common.exception.BusinessException;
import com.net.common.util.PhoneUtil;
import com.net.common.util.RandomUtil;
import com.net.xpay.common.service.CheckCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * @author on 08/02/2018.
 */
@Slf4j
@Service
public class CheckCodeServiceImpl implements CheckCodeService {

    @Autowired
    private CheckCodeManager checkCodeManager;

    @Autowired
    private CoreProperties coreProperties;

    @Autowired
    private EnvironmentHelper environmentHelper;

    @Autowired
    private SmsHelper smsHelper;

    @Autowired
    private CheckCodeLogManager checkCodeLogManager;

    @Override
    public CheckCode sendCheckCode(String mobile, CheckCodeType type, String ip) {
        log.info("send check code|mobile={}|type={}", mobile, type);
        if (!PhoneUtil.isEffectiveMobile(mobile)) {
            throw new BusinessException(PoseidonErrorCode.MOBILE_ERROR, "手机号格式不正确");
        }
        if (type == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "验证码类型不正确");
        }
        CheckCode checkCode = checkCodeManager.findByMobileAndType(mobile, type);
        if (checkCode == null) {
            checkCode = CheckCode.getInstance(mobile, type);
            if("18888888888".equals(mobile)){
                checkCode.setCode("888888");
            }else {
                checkCode.setCode("000000");
            }
            checkCode.setExpiredTime(LocalDateTime.now().plusMinutes(CoreConstant.CHECK_CODE_TIME_OUT));
            checkCode.setIp(ip);
            checkCodeManager.save(checkCode);

            CheckCodeLog checkCodeLog = CheckCodeLog.getInstance(checkCode.getId(), mobile, type);
            checkCodeLog.setCode(checkCode.getCode());
            checkCodeLog.setExpiredTime(checkCode.getExpiredTime());
            checkCodeLog.setIp(ip);
            checkCodeLogManager.save(checkCodeLog);
        } else {
            if (LocalDateTime.now().isBefore(checkCode.getSendTime().plusMinutes(CoreConstant.CHECK_CODE_INTERVAL))) {
                throw new BusinessException(PoseidonErrorCode.CHECK_CODE_TOO_BUSY, "验证码请求太频繁,请至少间隔一分钟在处理");
            }
            if (LocalDateTime.now().isAfter(checkCode.getExpiredTime())) {
                if("18888888888".equals(mobile)){
                    checkCode.setCode("888888");
                }else {
                    checkCode.setCode("000000");
                }
                checkCode.setExpiredTime(LocalDateTime.now().plusMinutes(CoreConstant.CHECK_CODE_TIME_OUT));
            }
            checkCode.setSendTime(LocalDateTime.now());
            checkCode.setIp(ip);
            checkCodeManager.update(checkCode);

            CheckCodeLog checkCodeLog = CheckCodeLog.getInstance(checkCode.getId(), mobile, type);
            checkCodeLog.setCode(checkCode.getCode());
            checkCodeLog.setExpiredTime(checkCode.getExpiredTime());
            checkCodeLog.setIp(ip);
            checkCodeLogManager.save(checkCodeLog);
        }

//        if (environmentHelper.isDevOrLocal()) {
//            return checkCode;
//        }

        smsHelper.sendSms(mobile, "您的验证码是" + checkCode.getCode() + "。如非本人操作，请忽略本短信");

        return checkCode;
    }

    @Override
    public CheckCode sendCheckCodeWithRelatedId(String mobile, CheckCodeType type, String ip, Long relatedId) {
        log.info("sendCheckCodeWithRelatedId|mobile={}|type={}|ip={}|relatedId={}", mobile, type, ip, relatedId);
        if (!PhoneUtil.isEffectiveMobile(mobile)) {
            throw new BusinessException(PoseidonErrorCode.MOBILE_ERROR, "手机号格式不正确");
        }
        if (type == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "验证码类型不正确");
        }
        CheckCode checkCode = checkCodeManager.findLastByRelatedId(mobile, type, relatedId);
        if (checkCode == null) {
            checkCode = CheckCode.getInstance(mobile, type);
            checkCode.setCode("000000");
            checkCode.setExpiredTime(LocalDateTime.now().plusMinutes(CoreConstant.CHECK_CODE_TIME_OUT));
            checkCode.setRelatedId(relatedId);
            checkCode.setIp(ip);
            checkCodeManager.save(checkCode);

            CheckCodeLog checkCodeLog = CheckCodeLog.getInstance(checkCode.getId(), mobile, type);
            checkCodeLog.setCode(checkCode.getCode());
            checkCodeLog.setExpiredTime(checkCode.getExpiredTime());
            checkCodeLog.setRelatedId(relatedId);
            checkCodeLog.setIp(ip);
            checkCodeLogManager.save(checkCodeLog);
        } else {
            if (LocalDateTime.now().isBefore(checkCode.getSendTime().plusMinutes(CoreConstant.CHECK_CODE_INTERVAL))) {
                throw new BusinessException(PoseidonErrorCode.CHECK_CODE_TOO_BUSY, "验证码请求太频繁,请至少间隔一分钟在处理");
            }

            checkCode = CheckCode.getInstance(mobile, type);
            checkCode.setCode("000000");
            checkCode.setExpiredTime(LocalDateTime.now().plusMinutes(CoreConstant.CHECK_CODE_TIME_OUT));
            checkCode.setRelatedId(relatedId);
            checkCode.setIp(ip);
            checkCodeManager.save(checkCode);

            CheckCodeLog checkCodeLog = CheckCodeLog.getInstance(checkCode.getId(), mobile, type);
            checkCodeLog.setCode(checkCode.getCode());
            checkCodeLog.setExpiredTime(checkCode.getExpiredTime());
            checkCodeLog.setRelatedId(relatedId);
            checkCodeLog.setIp(ip);
            checkCodeLogManager.save(checkCodeLog);
        }

        smsHelper.sendSms(mobile, "您的验证码是" + checkCode.getCode() + "。如非本人操作，请忽略本短信");

        return checkCode;
    }
}
